class HttpRequest {
  /**
   * 发送 GET 请求
   * @param {string} url 请求地址
   * @param {Object} params 请求参数
   * @param {Object} options 额外配置
   * @returns {Promise} 
   */
  static async get(url, params = {}, options = {}) {
    // 处理查询参数
    const queryString = Object.keys(params).map(key => 
      `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
    ).join('&');
    
    const requestUrl = queryString ? `${url}?${queryString}` : url;
    
    const defaultOptions = {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        ...options.headers
      },
      ...options
    };
    
    return this._fetch(requestUrl, defaultOptions);
  }

  /**
   * 发送 POST 请求
   * @param {string} url 请求地址
   * @param {Object} data 请求体数据
   * @param {Object} options 额外配置
   * @returns {Promise}
   */
  static async post(url, data = {}, options = {}) {
    const defaultOptions = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        ...options.headers
      },
      body: JSON.stringify(data),
      ...options
    };
    
    return this._fetch(url, defaultOptions);
  }

  /**
   * 内部fetch方法
   * @param {string} url 请求地址
   * @param {Object} options 请求配置
   * @returns {Promise}
   */
  static async _fetch(url, options = {}) {
    // 设置超时
    const { timeout = 10000 } = options;
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), timeout);
    
    try {
      const response = await fetch(url, {
        ...options,
        signal: controller.signal
      });
      
      clearTimeout(timer);
      
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      
      // 根据响应头决定如何解析响应体
      const contentType = response.headers.get('content-type');
      if (contentType && contentType.includes('application/json')) {
        return await response.json();
      }
      return await response.text();
    } catch (error) {
      clearTimeout(timer);
      if (error.name === 'AbortError') {
        throw new Error('请求超时');
      }
      throw error;
    }
  }
}